# coding:utf-8
# https://www.cnblogs.com/zhiyiYo/p/15676079.html
import os
import random
import sys
import time
from datetime import datetime

import pytz

import resources.resource_rc
from PyQt5.QtCore import QRect, QRectF, QSize, Qt, QCoreApplication, pyqtSignal, QPoint, QDir, QTimer, QEvent
from PyQt5.QtGui import QPainter, QPixmap, QWheelEvent, QKeySequence, QPen, QBrush, QTransform, QFont, QTouchEvent, \
    QPainterPath, QColor
from PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsPixmapItem,
                             QGraphicsScene, QGraphicsView, QShortcut, QFileDialog, QGraphicsRectItem,
                             QGraphicsLineItem, QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsEllipseItem)

from serialPort import SerialPortWindow, cm3_pb2
from utils.pictureHandlers import PicturesReader

#############################################################
# moveTo()函数隐式启动一个新的子路径，并关闭前一个子路径。
# 另一种启动新子路径的方法是调用closeSubpath()函数，该函数通过将currentPosition()中的一行添加回路径的起始位置来关闭当前路径。
# 请注意，新路径将具有（0,0）作为其初始currentPosition()。
#############################################################
from utils.sqlite3Handlers import Sqlite3Handler


class ContinueTouchWidget(QGraphicsView):
    """ 图片查看器 """

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        ## 加载配置文件
        import utils.configHandlers
        self.myConfig = utils.configHandlers.configHandler.configs
        # 引入可控串口信息窗口
        self.serialPortWin = self.myConfig.serialPortWin
        ## 加载数据库
        timeStr = datetime.now(pytz.timezone('Asia/Shanghai')).strftime("touchLog_%m-%d_%H-%M")
        self.sqlite3Handler = Sqlite3Handler(db_path='./data/records/', db_name=f'{timeStr}_BoevxaDb.db')
        # self.sqlite3Handler.InsertSingleData(signal=1, count=10, points='(1,3)/(2,4)/(3,4)/')
        #########################~~调试用~~#################################
        # 引入可控串口信息窗口
        if type(self.myConfig.serialPortWin) == type(SerialPortWindow()):
            self.serialPortWin = self.myConfig.serialPortWin
            # self.textNotice.setText("正在检测串口")
        else:
            self.serialPortWin = SerialPortWindow()
            self.myConfig.serialPortWin = self.serialPortWin
        ###########################################################
        # 将form2的信号_singal_2和主界面的getData_F2连接
        self.serialPortWin.serialPortSignal.connect(self.RecvSerialData)
        # 快捷键
        self.ShortcutFun()
        self.setToolTip('全屏与退出全屏：\n               双击 或者 F11')
        # 初始化小部件
        self.__initWidget()
        # 模拟数据
        # self.timer_creat_delay = 50
        # self.timer_creat = QTimer()
        # self.timer_creat.timeout.connect(self.CreateDataFun)
        # self.timer_creat.start(self.timer_creat_delay)
        # 记录数据重置
        self.touchMsgCount = 0
        self.touchEventCount = 0
        self.LogReInit()
        # 初始画布
        self.CleanFun()

    def CreateDataFun(self):
        self.timer_creat.stop()
        tempPointsSet = set()
        for i in range(10):
            tempPointsSet.add(
                f"({random.randint(0, 2560) + 0.01 * random.randint(0, 99)},{random.randint(0, 2560) + 0.01 * random.randint(0, 99)})")
        dictData = {
            'type': 'rece_protobuf',
            'data': {"msg_type": "Points", "points": {"count": 10, "list": str(tempPointsSet)}}
        }
        self.RecvSerialData(dictData)
        self.timer_creat.start(self.timer_creat_delay)

    def LogReInit(self):
        self.maxTouchCount = 0
        # [0] 鼠标事件与第一个触摸点 [1]...[9] 其他触摸点
        self.touchPoints = set()
        self.dbID = -1
        self.SingIn = -1
        # self.CleanFun()

    def ParseCoordFun(self, bytes_data):
        point_list = []
        point_x = b'0000000000000000'
        point_y = b'0000000000000000'
        # for idx in range(result_len):
        #     print(hex(result[idx]), '\t' + str(idx) + '\t', result[idx])
        idx = 0
        for item in bytes_data:
            idx += 1
            if idx % 4 == 1:
                point_x = item
                # print(hex(point_x), bin(point_x), hex(item), bin(item))
            if idx % 4 == 2:
                point_x = point_x + (item << 8)
            if idx % 4 == 3:
                point_y = item
            if idx % 4 == 0:
                point_y = point_y + (item << 8)
                point_list.append(f"({point_y},{point_x})")
                point_x = b'0000000000000000'
                point_y = b'0000000000000000'
        return point_list

    def RecvSerialData(self, dataDict: dict):
        typeStr = dataDict.get('type', 'null').strip()
        if typeStr == 'rece_protobuf':
            display = dataDict.get('data', '')
            print(display)
            if display.msg_type == cm3_pb2.SingIn:
                if self.SingIn < display.SingIn:
                    # print(display)
                    self.LogReInit()
                    self.dbID = self.sqlite3Handler.InsertTouchLog(signal=display.SingIn, count=None, points=None)
                    self.touchMsgCount += 1
                    self.touchMsgText.setText(f'收到USB触摸信号：{self.touchMsgCount} 次')
                self.SingIn = display.SingIn
            elif display.msg_type == cm3_pb2.Points:
                # print(self.touchPoints)
                # print(type(self.touchPoints))
                # print('self.touchPoints', self.touchPoints)
                if display.points.count > self.maxTouchCount:
                    self.maxTouchCount = display.points.count
                    self.touchPoints = self.ParseCoordFun(display.points.list)
                    self.UpdateDbData()
                # id_x = 0
                # for item in self.touchPoints:
                #     self.DrawQGraphicsEllipse(ind_color=id_x, point_x=eval(item)[0], point_y=eval(item)[1])
                #     id_x += 1
                self.touchEventCount += 1
                self.touchEventText.setText(f'收到触摸事件：{self.touchEventCount} 次 , {len(self.touchPoints)} 点')
            # if display.msg_type == cm3_pb2.Points:
            #     print(display)

    def UpdateDbData(self):
        self.sqlite3Handler.UpdateTouchLog(search_id=self.dbID, filed='count', value=self.maxTouchCount)
        self.sqlite3Handler.UpdateTouchLog(search_id=self.dbID, filed='points', value=str(self.touchPoints))

    def ShortcutFun(self):
        # 快捷键 F11
        # 全屏
        self.screenStatus = 'Normal'
        screenShortcut = QShortcut(QKeySequence(Qt.Key_F11), self)
        screenShortcut.activated.connect(self.WindowSizeFun)
        # 快捷键 F5
        screenShortcut2 = QShortcut(QKeySequence(Qt.Key_F5), self)
        screenShortcut2.activated.connect(self.CleanFun)

    def CleanFun(self):
        self.graphicsScene.clear()
        # 画图初始化
        self.DrawInit()

    def WindowSizeFun(self):
        # print(toStatus)
        if self.screenStatus == 'Normal':
            self.showFullScreen()
            self.screenStatus = 'FullScreen'
        else:
            self.showNormal()
            self.screenStatus = 'Normal'

    def __initWidget(self):
        """ 初始化小部件 """
        self.resize(1800, 1200)
        # 隐藏滚动条
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # 以鼠标所在位置为锚点进行缩放
        self.setTransformationAnchor(self.AnchorUnderMouse)

        # 平滑缩放
        # self.pixmapItem.setTransformationMode(Qt.SmoothTransformation)
        self.setRenderHints(QPainter.Antialiasing |
                            QPainter.SmoothPixmapTransform)

        # 设置场景
        # self.graphicsScene.addItem(self.pixmapItem)
        # 创建场景
        self.graphicsScene = QGraphicsScene()
        self.graphicsScene.clearSelection()  # 【清除选择】
        self.setScene(self.graphicsScene)
        self.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.setSceneRect(0, 0, 1800, 1200)  # fix scene size 500 500
        self.setRenderHint(QPainter.Antialiasing)  ##设置视图的抗锯齿渲染模式。

    def DrawInit(self):
        self.colorList = [Qt.yellow, Qt.red, Qt.green, Qt.blue, Qt.magenta, Qt.darkGreen, Qt.color1, Qt.cyan, Qt.gray,
                          Qt.darkRed, Qt.darkBlue]

        self.cycleRadius = 60
        self.pathPenWidth = 9
        # 提示文字
        # font = QFont()  # 实例化字体对象
        # font.setFamily("华文琥珀")  # 字体
        # font.setBold(True)  # 加粗
        # font.setItalic(True)  # 斜体
        # font.setStrikeOut(True)  # 删除线
        # font.setUnderline(True)  # 下划线
        # font.setPointSize(23)  # 字体大小
        # font.setWeight(25)  # 可能是字体的粗细
        self.touchMsgText = QGraphicsSimpleTextItem(f'收到USB触摸信号：{self.touchMsgCount} 次')
        # self.touchMsgText.setPen(QPen(QColor(Qt.white)))
        self.touchMsgText.setPos(self.size().width() / 2 + 33, self.size().height() / 2)
        self.touchMsgText.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
        self.graphicsScene.addItem(self.touchMsgText)
        self.touchMsgText.setZValue(5)
        self.touchMsgText.setScale(2)

        self.touchEventText = QGraphicsSimpleTextItem(f'模拟触摸事件：{self.touchEventCount} 次 , {0} 点')
        # self.touchEventText.setPen(QPen(QColor(Qt.white)))
        # touchEventText.setPos(self.myConfig.screenLength / 8, self.myConfig.screenWidth / 2)
        self.touchEventText.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable)
        self.graphicsScene.addItem(self.touchEventText)
        self.touchEventText.setZValue(5)
        self.touchEventText.setScale(2)

    def DrawQGraphicsEllipse(self, ind_color, point_x, point_y):
        try:
            self.cycle000 = QGraphicsEllipseItem(point_x - self.cycleRadius / 2, point_y - self.cycleRadius / 2,
                                                 self.cycleRadius, self.cycleRadius)
            self.cycle000.setPen(QColor(self.colorList[ind_color]))
            self.graphicsScene.addItem(self.cycle000)
        except Exception as e:
            print('Error 2:', e)


if __name__ == '__main__':
    # QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    # QApplication.setAttribute( Qt.AA_Use96Dpi)
    app = QApplication(sys.argv)
    font = QFont("宋体")
    pointsize = font.pointSize()
    font.setPixelSize(int(pointsize * 90 / 72))
    app.setFont(font)
    # myWin = MyMainWindow()
    w = ContinueTouchWidget()
    # 首先设置接收触控事件
    # w.setAttribute(Qt.WA_AcceptTouchEvents, True)
    w.show()
    sys.exit(app.exec_())
